/**
 * 统计页面核心逻辑
 * 负责数据获取、图表渲染和用户交互
 */

class StatsManager {
    constructor() {
        this.charts = {
            defectTrend: null,
            passFailPie: null,
            defectType: null,
            heatmap: null
        };

        this.currentData = {
            basic: null,
            defectTypes: null,
            timeRange: null
        };

        this.init();
    }

    init() {
        this.initEventListeners();
        this.initCharts();
        this.updateLastUpdateTime();
        this.loadInitialData();
    }

    initEventListeners() {
        // 时间范围类型切换
        document.getElementById('timeRangeType').addEventListener('change', this.toggleTimeRangeInputs.bind(this));

        // 应用查询按钮
        document.getElementById('applyQuery') && document.getElementById('applyQuery').addEventListener('click', this.applyTimeRange.bind(this));

        // 刷新按钮
        document.getElementById('refreshBtn') && document.getElementById('refreshBtn').addEventListener('click', this.refreshData.bind(this));

        // 缺陷图表类型切换
        // document.getElementById('defectChartType').addEventListener('change', this.switchDefectChart.bind(this));

        // 热力图时间单位切换
        document.getElementById('heatmapTimeUnit').addEventListener('change', this.updateHeatmap.bind(this));
    }

    toggleTimeRangeInputs() {
        const timeRangeType = document.getElementById('timeRangeType').value;
        const recentGroup = document.getElementById('recentTimeGroup');
        const customGroup = document.getElementById('customTimeGroup');

        if (timeRangeType === 'recent') {
            recentGroup.style.display = 'flex';
            customGroup.style.display = 'none';
        } else {
            recentGroup.style.display = 'none';
            customGroup.style.display = 'flex';
        }
    }

    getTimeRangeSpec() {
        const timeRangeType = document.getElementById('timeRangeType').value;

        if (timeRangeType === 'recent') {
            const unit = document.getElementById('timeUnit').value;
            const amount = document.getElementById('timeAmount').value;
            if (!amount || isNaN(amount) || amount < 1 || amount > 1000) {
                this.showError('最近时间范围数值必须在1到1000之间');
                return null;
            }
            return `latest_${unit}:${amount}`;
        } else {
            const startTime = document.getElementById('startTime').value;
            const endTime = document.getElementById('endTime').value;

            if (!startTime || !endTime) {
                this.showError('请选择开始时间和结束时间');
                return null;
            }

            return {
                start: startTime.replace('T', ' '),
                end: endTime.replace('T', ' ')
            };
        }
    }

    getResampleFreq() {
        const mode = document.getElementById('resampleMode').value;
        if (mode === 'preset') {
            return document.getElementById('resamplePreset').value;
        } else if (mode === 'custom') {
            const value = parseInt(document.getElementById('resampleValue').value, 10);
            const unit = document.getElementById('resampleUnit').value;
            if (isNaN(value) || value < 1 || value > 1000) {
                this.showError('重采样数值必须在1到1000之间');
                return null;
            }
            return `${value}${unit}`;
        }
        return null;
    }

    async applyTimeRange() {
        const timeRangeSpec = this.getTimeRangeSpec();
        if (!timeRangeSpec) return;

        const resampleFreq = this.getResampleFreq();
        if (resampleFreq === null)
            return;

        this.showLoading(true);

        try {
            await this.loadData(timeRangeSpec, resampleFreq);
            this.updateSummary();
        } catch (error) {
            this.showError('数据加载失败: ' + error.message);
        } finally {
            this.showLoading(false);
        }
    }

    async refreshData() {
        const timeRangeSpec = this.getTimeRangeSpec() || 'latest_days:1';
        const resample_freq = this.getResampleFreq();
        if (resample_freq === null)
            return;

        this.showLoading(true);

        try {
            await this.loadData(timeRangeSpec, resample_freq);
            this.updateLastUpdateTime();
            this.updateSummary();
        } catch (error) {
            this.showError('数据刷新失败: ' + error.message);
        } finally {
            this.showLoading(false);
        }
    }

    async loadInitialData() {
        const defaultTimeRange = 'latest_days:1';
        const defaultResample = '1h';

        this.showLoading(true);

        try {
            await this.loadData(defaultTimeRange, defaultResample);
            this.updateSummary();
        } catch (error) {
            this.showError('初始数据加载失败: ' + error.message);
        } finally {
            this.showLoading(false);
        }
    }

    async loadData(timeRangeSpec, resampleFreq) {
        // 并行加载基础统计和缺陷类型统计
        const [basicStats, defectStats] = await Promise.all([
            this.fetchBasicStats(timeRangeSpec, resampleFreq),
            this.fetchDefectTypeStats(timeRangeSpec, resampleFreq)
        ]);

        this.currentData.basic = basicStats;
        this.currentData.defectTypes = defectStats;
        this.currentData.timeRange = timeRangeSpec;

        this.updateAllDisplays();
    }

    async fetchBasicStats(timeRangeSpec, resampleFreq) {
        const response = await fetch('/api/statistics/detail', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                type: 'basic',
                time_range_spec: timeRangeSpec,
                resample_freq: resampleFreq
            })
        });

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        return await response.json();
    }

    async fetchDefectTypeStats(timeRangeSpec, resampleFreq) {
        const response = await fetch('/api/statistics/detail', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                type: 'defect_type',
                time_range_spec: timeRangeSpec,
                resample_freq: resampleFreq
            })
        });

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        return await response.json();
    }

    updateAllDisplays() {
        this.updateStatCards();
        this.updateDefectTrendChart();
        this.updatePassFailPieChart();
        this.updateDefectTypeChart();
        this.updateDefectDetailTable();
        this.updateHeatmap();
    }

    updateStatCards() {
        if (!this.currentData.basic?.details) return;

        // 计算总体统计
        const totalStats = this.calculateTotalStats(this.currentData.basic.details);

        // 更新统计卡片
        this.updateElement('totalProcessed', totalStats.total.toLocaleString());
        this.updateElement('totalPassed', totalStats.passed.toLocaleString());
        this.updateElement('totalDefective', totalStats.defective.toLocaleString());
        this.updateElement('passRate', `${(totalStats.passRate * 100).toFixed(2)}%`);
    }

    calculateTotalStats(timeSeriesData) {
        let total = 0, defective = 0, passed = 0;

        timeSeriesData.forEach(item => {
            total += item.total || 0;
            defective += item.defective || 0;
        });

        passed = total - defective;
        const passRate = total > 0 ? passed / total : 0;

        return { total, defective, passed, passRate };
    }

    initCharts() {
        this.initDefectTrendChart();
        this.initPassFailPieChart();
        this.initDefectTypeChart();
        this.initHeatmapChart();
    }

    initDefectTrendChart() {
        const ctx = document.getElementById('defectTrendChart');
        if (!ctx) return;

        this.charts.defectTrend = new Chart(ctx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: '缺陷率',
                    data: [],
                    borderColor: '#ff6b6b',
                    backgroundColor: 'rgba(255, 107, 107, 0.1)',
                    tension: 0.4,
                    fill: true
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        display: true
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        max: 1,
                        ticks: {
                            callback: function (value) {
                                return (value * 100).toFixed(0) + '%';
                            }
                        }
                    }
                }
            }
        });
    }

    initPassFailPieChart() {
        const ctx = document.getElementById('passFailPieChart');
        if (!ctx) return;

        this.charts.passFailPie = new Chart(ctx, {
            type: 'pie',
            data: {
                labels: ['合格', '缺陷'],
                datasets: [{
                    data: [0, 0],
                    // backgroundColor: ['#2ecc71', '#e74c3c'],
                    backgroundColor: [
                        'rgba(52, 199, 89, 0.85)', // 合格
                        'rgba(255, 59, 48, 0.85)'   // 缺陷
                    ],
                    borderWidth: 2,
                    borderColor: '#fff',
                    hoverOffset: 6,
                    borderRadius: 6
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        position: 'bottom'
                    }
                }
            }
        });
    }

    initDefectTypeChart() {
        const ctx = document.getElementById('defectTypeChart');
        if (!ctx) return;

        this.charts.defectType = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: [],
                datasets: [{
                    label: '缺陷数量',
                    data: [],
                    backgroundColor: [
                        '#ff6b6b', '#4ecdc4', '#45b7d1',
                        '#f1c40f', '#e67e22', '#2ecc71'
                    ],
                    borderWidth: 1,
                    borderRadius: 12
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        display: false
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                    }
                }
            }
        });
    }

    initHeatmapChart() {
        const ctx = document.getElementById('defectHeatmapChart');
        if (!ctx) return;

        // 热力图柱状图实现
        this.charts.heatmap = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: [],
                datasets: []
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        position: 'top'
                    }
                },
                scales: {
                    x: {
                        stacked: true
                    },
                    y: {
                        stacked: true,
                        beginAtZero: true
                    }
                }
            }
        });
    }

    updateDefectTrendChart() {
        if (!this.charts.defectTrend || !this.currentData.basic?.details) return;

        const data = this.currentData.basic.details;
        const labels = data.map(item => this.formatTimestamp(item.ts));
        const defectRates = data.map(item => item.defect_rate || 0);

        this.charts.defectTrend.data.labels = labels;
        this.charts.defectTrend.data.datasets[0].data = defectRates;
        this.charts.defectTrend.update();
    }

    updatePassFailPieChart() {
        if (!this.charts.passFailPie || !this.currentData.basic?.details) return;

        const totalStats = this.calculateTotalStats(this.currentData.basic.details);

        this.charts.passFailPie.data.datasets[0].data = [
            totalStats.passed,
            totalStats.defective
        ];
        this.charts.passFailPie.update();
    }

    updateDefectTypeChart() {
        if (!this.charts.defectType || !this.currentData.defectTypes?.details) return;

        // 聚合所有时间段的缺陷类型数据
        const defectTypeStats = this.aggregateDefectTypes(this.currentData.defectTypes.details);

        const labels = defectTypeStats.map(item => this.translateDefectType(item.type));
        const data = defectTypeStats.map(item => item.count);

        this.charts.defectType.data.labels = labels;
        this.charts.defectType.data.datasets[0].data = data;
        this.charts.defectType.update();
    }

    aggregateDefectTypes(timeSeriesData) {
        const typeMap = {};

        timeSeriesData.forEach(timePoint => {
            if (timePoint.defect_types) {
                timePoint.defect_types.forEach(defectType => {
                    const type = defectType.type;
                    if (!typeMap[type]) {
                        typeMap[type] = { type, count: 0 };
                    }
                    typeMap[type].count += defectType.count || 0;
                });
            }
        });

        return Object.values(typeMap).sort((a, b) => b.count - a.count);
    }

    // switchDefectChart() {
    //     const chartType = document.getElementById('defectChartType').value;

    //     if (this.charts.defectType) {
    //         this.charts.defectType.destroy();
    //     }

    //     const ctx = document.getElementById('defectTypeChart');
    //     this.charts.defectType = new Chart(ctx, {
    //         type: chartType,
    //         data: {
    //             labels: [],
    //             datasets: [{
    //                 label: '缺陷数量',
    //                 data: [],
    //                 backgroundColor: [
    //                     '#ff6b6b', '#4ecdc4', '#45b7d1',
    //                     '#f1c40f', '#e67e22', '#2ecc71'
    //                 ],
    //                 borderWidth: 1,
    //                 borderRadius: chartType === 'bar' ? 12 : 0,
    //             }]
    //         },
    //         options: {
    //             responsive: true,
    //             maintainAspectRatio: false,
    //             plugins: {
    //                 legend: {
    //                     display: chartType !== 'bar',
    //                     position: 'bottom'
    //                 }
    //             },
    //             scales: chartType === 'bar' ? {
    //                 y: {
    //                     beginAtZero: true
    //                 }
    //             } : {}
    //         }
    //     });

    //     this.updateDefectTypeChart();
    // }

    switchChartType(chartType, buttonElement) {
        // 更新按钮激活状态
        const allButtons = document.querySelectorAll('.chart-type-btn');
        allButtons.forEach(btn => btn.classList.remove('active'));
        buttonElement.classList.add('active');

        // 销毁现有图表
        if (this.charts.defectType) {
            this.charts.defectType.destroy();
        }

        // 创建新图表
        const ctx = document.getElementById('defectTypeChart');
        this.charts.defectType = new Chart(ctx, {
            type: chartType,
            data: {
                labels: [],
                datasets: [{
                    label: '缺陷数量',
                    data: [],
                    backgroundColor: [
                        '#ff6b6b', '#4ecdc4', '#45b7d1',
                        '#f1c40f', '#e67e22', '#2ecc71'
                    ],
                    borderWidth: 1,
                    borderRadius: chartType === 'bar' ? 12 : 0,
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        display: chartType !== 'bar',
                        position: 'bottom'
                    }
                },
                scales: chartType === 'bar' ? {
                    y: {
                        beginAtZero: true
                    }
                } : {}
            }
        });

        // 更新图表数据
        this.updateDefectTypeChart();
    }

    updateDefectDetailTable() {
        const tbody = document.getElementById('defectDetailTableBody');
        if (!tbody || !this.currentData.defectTypes?.details) return;

        const defectTypeStats = this.aggregateDefectTypes(this.currentData.defectTypes.details);
        const totalDefects = defectTypeStats.reduce((sum, item) => sum + item.count, 0);

        tbody.innerHTML = '';

        defectTypeStats.forEach(defectType => {
            const row = document.createElement('tr');
            const ratio = totalDefects > 0 ? (defectType.count / totalDefects * 100).toFixed(1) : '0.0';

            row.innerHTML = `
                <td>${this.translateDefectType(defectType.type)}</td>
                <td>${defectType.count}</td>
                <td>${ratio}%</td>
            `;

            tbody.appendChild(row);
        });
    }

    updateHeatmap() {
        if (!this.charts.heatmap || !this.currentData.defectTypes?.details) return;

        const timeUnit = document.getElementById('heatmapTimeUnit').value;
        const heatmapData = this.processHeatmapData(this.currentData.defectTypes.details, timeUnit);

        // 格式化标签以获得更好的显示效果
        const formattedLabels = heatmapData.labels.map(label =>
            this.formatTimeLabel(timeUnit, label)
        );

        this.charts.heatmap.data.labels = formattedLabels;
        this.charts.heatmap.data.datasets = heatmapData.datasets;

        // 更新图表标题以反映当前的时间单位
        const unitNames = {
            'hour': '小时',
            'day': '天',
            'week': '周',
            'month': '月'
        };

        if (this.charts.heatmap.options.plugins.title) {
            this.charts.heatmap.options.plugins.title.text = `缺陷类型分布 (按${unitNames[timeUnit] || '天'}统计)`;
        }

        this.charts.heatmap.update();
    }

    processHeatmapData(timeSeriesData, timeUnit) {
        if (!timeSeriesData || timeSeriesData.length === 0) {
            return { labels: [], datasets: [] };
        }

        const defectTypes = ['inclusion', 'patches', 'scratches', 'pitted_surface', 'crazing', 'rolled_in_scale'];
        const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#f1c40f', '#e67e22', '#2ecc71'];

        // 根据时间单位分组数据
        const groupedData = this.groupDataByTimeUnit(timeSeriesData, timeUnit);

        // 生成标签
        const labels = Object.keys(groupedData).sort();

        // 为每个缺陷类型创建数据集
        const datasets = defectTypes.map((type, index) => ({
            label: this.translateDefectType(type),
            data: labels.map(label => {
                const groupData = groupedData[label];
                // 计算该时间段内该类型缺陷的总数
                return groupData.reduce((sum, item) => {
                    const typeData = item.defect_types?.find(dt => dt.type === type);
                    return sum + (typeData ? typeData.count : 0);
                }, 0);
            }),
            backgroundColor: colors[index] || '#95a5a6',
            borderColor: colors[index] || '#95a5a6',
            borderWidth: 1
        }));

        return { labels, datasets };
    }

    groupDataByTimeUnit(data, timeUnit) {
        const grouped = {};

        data.forEach(item => {
            const date = new Date(item.timestamp);
            let key;

            switch (timeUnit) {
                case 'hour':
                    // 按小时分组：YYYY-MM-DD HH
                    key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:00`;
                    break;

                case 'day':
                    // 按天分组：YYYY-MM-DD
                    key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
                    break;

                case 'week':
                    // 按周分组：获取该周的周一日期
                    const monday = this.getMonday(date);
                    key = `${monday.getFullYear()}-${String(monday.getMonth() + 1).padStart(2, '0')}-${String(monday.getDate()).padStart(2, '0')} (周)`;
                    break;

                case 'month':
                    // 按月分组：YYYY-MM
                    key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
                    break;

                default:
                    // 默认按天分组
                    key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
            }

            if (!grouped[key]) {
                grouped[key] = [];
            }
            grouped[key].push(item);
        });

        return grouped;
    }

    // 辅助方法：获取某个日期所在周的周一
    getMonday(date) {
        const d = new Date(date);
        const day = d.getDay();
        const diff = d.getDate() - day + (day === 0 ? -6 : 1); // 调整周日
        return new Date(d.setDate(diff));
    }

    // 如果你还需要更灵活的时间格式化
    formatTimeLabel(timeUnit, dateKey) {
        switch (timeUnit) {
            case 'hour':
                return dateKey; // 已经是 "YYYY-MM-DD HH:00" 格式

            case 'day':
                const dayDate = new Date(dateKey);
                return `${dayDate.getMonth() + 1}/${dayDate.getDate()}`;

            case 'week':
                return dateKey; // 已经包含 "(周)" 标识

            case 'month':
                const monthDate = new Date(dateKey + '-01');
                return `${monthDate.getFullYear()}年${monthDate.getMonth() + 1}月`;

            default:
                return dateKey;
        }
    }

    updateSummary() {
        if (!this.currentData.basic?.metadata) return;

        const metadata = this.currentData.basic.metadata;

        this.updateElement('summaryTimeRange', this.formatTimeRange(this.currentData.timeRange));
        this.updateElement('summaryResampleFrequency', this.getResampleFreq() || '--');
        this.updateElement('summaryLogFiles', metadata.log_files_found || '--');
        this.updateElement('summaryTotalRecords', metadata.total_records_found || '--');
    }

    // 工具函数
    updateElement(id, value) {
        const element = document.getElementById(id);
        if (element) {
            element.textContent = value;
        }
    }

    formatTimestamp(timestamp, format = 'MM-DD HH:mm') {
        if (!timestamp) return '--';

        try {
            const date = new Date(timestamp);
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hour = String(date.getHours()).padStart(2, '0');
            const minute = String(date.getMinutes()).padStart(2, '0');

            if (format === 'HH:mm') {
                return `${hour}:${minute}`;
            }
            return `${month}-${day} ${hour}:${minute}`;
        } catch (error) {
            return '--';
        }
    }

    formatTimeRange(timeRangeSpec) {
        if (typeof timeRangeSpec === 'string') {
            return timeRangeSpec;
        } else if (typeof timeRangeSpec === 'object') {
            return `${timeRangeSpec.start} 至 ${timeRangeSpec.end}`;
        }
        return '--';
    }

    translateDefectType(type) {
        const translations = {
            'inclusion': 'inclusion 夹杂物',
            'patches': 'patches 斑点',
            'scratches': 'scratches 划痕',
            'pitted_surface': 'pitted_surface 凹坑',
            'crazing': 'crazing 开裂',
            'rolled_in_scale': 'rolled_in_scale 卷入'
        };
        return translations[type] || type;
    }

    showLoading(show) {
        const indicator = document.getElementById('loadingIndicator');
        if (indicator) {
            indicator.style.display = show ? 'flex' : 'none';
        }
    }

    showError(message) {
        const modal = document.getElementById('errorModal');
        const messageEl = document.getElementById('errorMessage');

        if (modal && messageEl) {
            messageEl.textContent = message;
            modal.style.display = 'block';
        } else {
            alert(message);
        }
    }

    updateLastUpdateTime() {
        const now = new Date();
        const timeString = now.toLocaleString('zh-CN');
        this.updateElement('lastUpdateTime', `最后更新: ${timeString}`);
    }
}

// 全局函数
function goBack() {
    window.history.back();
}

function closeErrorModal() {
    const modal = document.getElementById('errorModal');
    if (modal) {
        modal.style.display = 'none';
    }
}

function toggleResampleInputs() {
    const mode = document.getElementById('resampleMode').value;
    document.getElementById('resamplePresetGroup').style.display = (mode === 'preset') ? '' : 'none';
    document.getElementById('resampleCustomGroup').style.display = (mode === 'custom') ? '' : 'none';
}

document.addEventListener('DOMContentLoaded', function () {
    window.statsManager = new StatsManager();
    toggleResampleInputs();
});

function exportDefectData() {
    // 导出缺陷数据功能
    // console.log('Export defect data');
    const table = document.getElementById('defectDetailTable');
    if (!table) {
        alert('缺陷数据表格未找到');
        return;
    }
    let csv = '';
    const rows = table.querySelectorAll('tr');
    rows.forEach(row => {
        const cols = row.querySelectorAll('th, td');
        const rowData = Array.from(cols).map(col => `"${col.innerText.replace(/"/g, '""')}"`).join(',');
        csv += rowData + '\r\n';
    });

    const now = new Date();
    const pad = n => n.toString().padStart(2, '0');
    const ts = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`;

    const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `缺陷数据类型_${ts}.csv`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function () {
    window.statsManager = new StatsManager();
});

// 修正HTML中的函数调用
function toggleTimeRangeInputs() {
    if (window.statsManager) {
        window.statsManager.toggleTimeRangeInputs();
    }
}

function applyTimeRange() {
    if (window.statsManager) {
        window.statsManager.applyTimeRange();
    }
}

function refreshData() {
    if (window.statsManager) {
        window.statsManager.refreshData();
    }
}

// function switchDefectChart() {
//     if (window.statsManager) {
//         window.statsManager.switchDefectChart();
//     }
// }

function switchChartType(chartType, buttonElement) {
    if (window.statsManager) {
        window.statsManager.switchChartType(chartType, buttonElement);
    }
}

function updateHeatmap() {
    if (window.statsManager) {
        window.statsManager.updateHeatmap();
    }
}

function saveChartImage(chartKey) {
    if (!window.statsManager || !window.statsManager.charts[chartKey]) {
        alert(`图表未加载或不存在: ${chartKey}`);
        return;
    }

    const chart = window.statsManager.charts[chartKey];
    const canvas = chart.canvas;

    const scale = 1;                    // 保存时放大倍数
    const canvasWidth = canvas.width;   // 图表宽度
    const canvasHeight = canvas.height; // 图表高度
    const padding = 40 * scale;         // 边距
    const titleHeight = 50 * scale;     // 标题栏高度

    const totalHeight = padding + titleHeight + 20 * scale + canvasHeight * scale + padding; // 总高度
    const totalWidth = padding + canvasWidth * scale + padding; // 总宽度

    const tmpCanvas = document.createElement('canvas');
    tmpCanvas.width = totalWidth;
    tmpCanvas.height = totalHeight;
    const ctx = tmpCanvas.getContext('2d');

    // 背景
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, tmpCanvas.width, tmpCanvas.height);

    // 标题
    const chartNames = {
        defectTrend: '缺陷趋势图',
        passFailPie: '合格率饼图',
        defectType: '缺陷类型分布',
        heatmap: '缺陷热力图'
    }
    ctx.fillStyle = '#333';
    ctx.font = `bold ${36 * scale}px "Segoe UI", Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    ctx.fillText(chartNames[chartKey] || '图表', tmpCanvas.width / 2, padding);

    // 图表
    ctx.drawImage(
        canvas,
        padding,
        padding + titleHeight + 20 * scale,
        canvasWidth * scale,
        canvasHeight * scale
    );

    // 时间戳
    const now = new Date();
    const pad = n => String(n).padStart(2, '0');
    const ts = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`;

    // 水印
    // ctx.font = `${18 * scale}px Arial`;
    // ctx.fillStyle = '#aaa';
    // ctx.textAlign = 'right';
    // ctx.fillText(`导出时间: ${ts}`, tmpCanvas.width - 40 * scale, tmpCanvas.height - 30 * scale);

    // 图表类型（for defectType图表）
    const chartTypes = {
        bar: '柱状图',
        pie: '饼图',
        doughnut: '环形图'
    }
    let chartNameForFilename = chartNames[chartKey] || 'chart';
    // if (chartKey === 'defectType') {
    //     const defectTypeElement = document.getElementById('defectChartType');
    //     let defectTypeName = defectTypeElement.value
    //     defectTypeName = chartTypes[defectTypeName] || '';
    //     chartNameForFilename += `${defectTypeName}`;
    // }
    if (chartKey === 'defectType') {
        const activeBtn = document.querySelector('.chart-type-btn.active');
        let defectTypeName = '';
        if (activeBtn) {
            const chartType = activeBtn.getAttribute('data-type');
            defectTypeName = chartTypes[chartType] || '';
        }
        chartNameForFilename += `${defectTypeName}`;
    }

    // 文件名
    const filename = `${chartNameForFilename}_${ts}.png`;

    tmpCanvas.toBlob(function (blob) {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = filename;

        document.body.appendChild(link);
        link.click();
        setTimeout(() => {
            document.body.removeChild(link);
            URL.revokeObjectURL(link.href);
        }, 100)
    }, 'image/png')
}